package vsvm.data.source;

import java.util.ArrayList;

import vsvm.data.model.AbstractAttribute;
import vsvm.data.model.AbstractDataModel;
import vsvm.data.model.CategorialAttribute;
import vsvm.data.model.NumericAttribute;
import vsvm.gui.Environment;
import vsvm.gui.forms.ConfigureDelimitedDataSourceDialog;

public class DelimitedFileDataSource extends FileDataSource {
	private static final long serialVersionUID = 100L;
	private String delimiter;

	public DelimitedFileDataSource(String filename) {
		this.filename = filename;
		this.delimiter = ",";
	}
	
	public DelimitedFileDataSource(String filename, String delimiter) {
		this.filename = filename;
		this.delimiter = delimiter;
	}
	
	
	@Override
	public void fill(AbstractDataModel model, AbstractAttribute classAttr) throws Exception {
		if (!opened) return;
		
		if (attributes == null) {
			readAttributes();
		}

		String line;
			
		try {
			model.setAttributes(attributes);
			ArrayList<double[]> data = new ArrayList<double[]>();
			//ArrayList<Double> y = new ArrayList<Double>();
			double[] vec;
			reset();
			while ( (line =  reader.readLine()) != null) {
				String[] vals = line.split(delimiter);
				if (vals.length != attributes.size()) {
					System.out.println("Invalid count of attributes");					
				} else {
					vec = new double[vals.length];
					for (int i = 0, j = 0; i < vals.length; i++) {
						//if (attributes.get(i) != classAttr)
							vec[j++] = attributes.get(i).toDouble(vals[i]);
						//else
							//y.add(attributes.get(i).toDouble(vals[i]));
							
					}
					data.add(vec);					
				}				
			}
			
			model.setData(data, model.getAtttributeIndex(classAttr));
		} catch (Exception e) {
			throw e;
		}
	}

	@Override
	public ArrayList<AbstractAttribute> readAttributes() {
		if (!opened) return null;

		attributes = new ArrayList<AbstractAttribute>();
		try {
			String line = reader.readLine();
			String[] vals = line.split(delimiter);
			int detected = 0;
			for (int i = 0; i < vals.length; i++) {
				if (vals[i] == "")
					attributes.add(null);			// TODO default numeric?
				else {
					try { 
						Double.parseDouble(vals[i]);
						attributes.add(new NumericAttribute( Integer.toString(i + 1) ));
					} catch (NumberFormatException e) {
						attributes.add(new CategorialAttribute(Integer.toString(i + 1)));						
					}
					++detected;
				}
			}			
		} catch (Exception e) {
			
		}

		return attributes;
	}
	
	public void configure() {
		ConfigureDelimitedDataSourceDialog dlg = new ConfigureDelimitedDataSourceDialog(
		Environment.getEnvironment().getMainFrame(), this);
		dlg.setVisible(true);		
	}


	public String getDelimiter() {
		return delimiter;
	}

	public void setDelimiter(String delimiter) {
		this.delimiter = delimiter;
	}
	
//	public String getRawData() {
//		return "1/n2/n3/n4/n5/n6/n7/n";
//	}


	
	 public static void main(String[] args) {
		 AbstractDataSource ds = new DelimitedFileDataSource("data\\ionosphere\\ionosphere.data");
		 
		 ds.open();
		 //ds.fill(adm, null);
		 ds.close();
     }

	public String getQuickInfo() {
		StringBuilder sb = new StringBuilder();
		sb.append("Delimited file data source" + Environment.newline);
		sb.append("File name:  " + filename + Environment.newline);
		sb.append("Delimiters:  " + delimiter + Environment.newline);
		return sb.toString();
	}
}
